package cn.lili.admin.service;

import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import cn.hutool.json.JSONUtil;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractStatusChangeNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

/**
 * 自定义通知
 *
 * @author moxingjian
 * @version 1.0
 * @date 2023-12-12 17:51
 * <p>
 * 版本更新：
 * 更新版本号    更新人      更新时间      更新内容
 */
@Slf4j
@Service
public class CustomNotifier extends AbstractStatusChangeNotifier {

    /**
     * 消息模板
     */
    private static final String template = "<<<%s>>> \n 【服务名】: %s(%s) \n 【状态】: %s(%s) \n 【服务ip】: %s \n 【详情】: %s";

    private String titleAlarm = "系统告警";

    private String titleNotice = "系统通知";

    private String[] ignoreChanges = new String[]{"UNKNOWN:UP", "DOWN:UP", "OFFLINE:UP"};

    @Resource
    private MailAccount mailAccount;

    public CustomNotifier(InstanceRepository repository) {
        super(repository);
    }


    /**
     * 应用状态变化通知
     *
     * @param event 事件，状态
     * @param instance 实例
     */
    @Override
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(() -> {
            if (event instanceof InstanceStatusChangedEvent) {
                log.info("Instance {} ({}) is {}", instance.getRegistration().getName(),
                        event.getInstance(),
                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());

                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
                String messageText = null;
                switch (status) {
                    // 健康检查没通过
                    case "DOWN":
                        log.info("发送 健康检查没通过 的通知！");
                        messageText = String
                                .format(template, titleAlarm, instance.getRegistration().getName(), event.getInstance(),
                                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "健康检查没通过通知",
                                        instance.getRegistration().getServiceUrl(), JSONUtil.toJsonStr(instance.getStatusInfo().getDetails()));
                        log.info(messageText);
                        break;
                    // 服务离线
                    case "OFFLINE":
                        log.info("发送 服务离线 的通知！");
                        messageText = String
                                .format(template, titleAlarm, instance.getRegistration().getName(), event.getInstance(),
                                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "服务离线通知",
                                        instance.getRegistration().getServiceUrl(), JSONUtil.toJsonStr(instance.getStatusInfo().getDetails()));
                        log.info(messageText);
                        break;
                    //服务上线
                    case "UP":
                        log.info("发送 服务上线 的通知！");
                        messageText = String
                                .format(template, titleNotice, instance.getRegistration().getName(), event.getInstance(),
                                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "服务上线通知",
                                        instance.getRegistration().getServiceUrl(), JSONUtil.toJsonStr(instance.getStatusInfo().getDetails()));
                        log.info(messageText);
                        break;
                    // 服务未知异常
                    case "UNKNOWN":
                        log.info("发送 服务未知异常 的通知！");
                        messageText = String
                                .format(template, titleAlarm, instance.getRegistration().getName(), event.getInstance(),
                                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "服务未知异常通知",
                                        instance.getRegistration().getServiceUrl(), JSONUtil.toJsonStr(instance.getStatusInfo().getDetails()));
                        log.info(messageText);
                        break;
                    default:
                        break;
                }
                // 发送邮件
                MailUtil.send(mailAccount, "939697374@qq.com", "SBA通知", messageText, false, null);
            } else {
                log.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(),
                        event.getType());
            }
        });
    }
}
